#include "head_c.h"

void* start_puts(void* p)
{
    portocol_t* portocol = (portocol_t*)p;
    char ip[20] = {0};
    getparameter("ip", ip);
    char port[10] = {0};
    getparameter("port", port);

    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in sockaddr;
    sockaddr.sin_family=AF_INET;
    sockaddr.sin_port=htons(atoi(port));
    sockaddr.sin_addr.s_addr=inet_addr(ip);

    connect(socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
    send(socket_fd, portocol, sizeof(portocol_t), MSG_NOSIGNAL);
    send(socket_fd, portocol, sizeof(portocol_t), MSG_NOSIGNAL);
    upload(portocol, socket_fd);
    close(socket_fd);

}

int do_puts(const portocol_t* portocol)
{
    pthread_t tid;
    portocol_t port_puts;
    memcpy(&port_puts, portocol, sizeof(portocol_t));
    pthread_create(&tid, NULL, start_puts, (void*)&port_puts);
    return 0;
}
int upload(const portocol_t* portocol, int socket_fd)
{


    char file_name[100] = {0};
    int index = 0;
    for(int i=0; i<strlen(portocol->arg); i++){
        if(portocol->arg[i] == '&'){
            index = i+1;
        }else if(portocol->arg[i] == 0){
            break;
        }
    }

    for(int i=0; i<strlen(portocol->arg); i++){
        if(portocol->arg[i+index] != 0){
            file_name[i] = portocol->arg[i+index];
        }else{
            break;
        }
    }
    LOG_WRITE(LOG_ERROR, "%s", file_name);

    // 打开文件获得文件大小
    int file_fd = open(file_name, O_RDWR);
    if(file_fd == -1){                                          
        send(socket_fd, "1", 1, MSG_NOSIGNAL);
        perror("open failed!\n");
        return -1;
    }
send(socket_fd, "0", 1, MSG_NOSIGNAL);

    struct stat st;
    if(fstat(file_fd, &st) == -1){
        perror("fstat failed!\n");
        return -1;
    }

    send(socket_fd, &st.st_size, sizeof(off_t), MSG_NOSIGNAL);


    //获取哈希值并发送给服务端      
    char buf[612];
    sprintf(buf, "sha1sum %s", file_name);
    FILE *pipe = popen(buf, "r");
    
    char hash[128] = {0};
    fread(hash, 1, sizeof(hash), pipe);
    pclose(pipe);
    int i = 0;
    while (hash[i] != '\0')
    {
        if (hash[i] == ' ')
        {
            hash[i] = '\0';
            break;
        }
        i++;
    }
int len = strlen(hash);
    LOG_WRITE(LOG_ERROR, "%s, %d", hash, len);
    send(socket_fd, &len, sizeof(int),MSG_NOSIGNAL);
    send(socket_fd, hash, len, MSG_NOSIGNAL);

    //接收参数判断传输类型
    int flag =-1; // 0全新上传， 1存在  2断点
    int flag_y = -1;
    recv(socket_fd, &flag, sizeof(int), MSG_WAITALL);
    recv(socket_fd, &flag_y, sizeof(int), MSG_WAITALL);
    if(flag == 1){
        printf("-----文件重名-----\n");
        return  0;
    }

    // TODO: --------------------

    if(flag ==0){
        // 全新上传
        sendfile(socket_fd,file_fd, 0,st.st_size   );
        printf("-----文件上传成功-----\n");
    }
    if(flag == 2){
        // 断点上传
        off_t upload_size;
        recv(socket_fd, &upload_size, sizeof(off_t), 0);
        //printf("upload_size： %ld \n", upload_size);

        void* mapped = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, file_fd, 0);
        // send(socket_fd, );
        int ret = send(socket_fd, mapped+upload_size, st.st_size - upload_size, MSG_NOSIGNAL);
        printf("send ret: %d \n", ret);
        munmap(mapped, st.st_size);
        LOG_WRITE(LOG_ERROR,"接受文件字节数：%s", ret);
        if(flag_y == 1){

            printf("-----文件上传成功-----\n");
        }else{
            printf("-----文件重名-----");
        }
    }
    if(flag == 3) {
        printf("-----急速秒传成功-----\n");
    }
    return 0;
}
